<?php
/**
 * Celebrio FileSystem module
 *
 * @copyright  Copyright (c) 2011 Celebrio Software
 * @package    Celebrio
 * @subpackage FileSystem
 */
namespace Celebrio\FileSystem;

use Nette\Object;
use Nette\Web\User;
use Nette\Environment;

use InvalidStateException;

use Celebrio\FileSystem\AccessDeniedException;
use Celebrio\FileSystem\FileNotFoundException;

/**
 * PermissionChecker provides the methods for checking whether
 * the User (given in the constructor) is allowed to access
 * the requested resource/privilege.
 *
 * @author pavel
 */
class PermissionChecker extends Object {


    /**
     * Currently logged user
     *
     * @var Nette\Web\User
     */
    private $user;
    
    private $fileAcl;

    
    public function __construct(/*const*/ User $user) {
        //$this->user = clone Environment::getUser();
        $this->user = clone $user;
        
        $this->fileAcl = new FileAcl();
        $this->user->setAuthorizationHandler($this->fileAcl);
    }

    public function __destruct() {
        unset ($this->user);

    }

    public function addResource(VirtualFile $file) {
        try {
            $this->fileAcl->addResource($file->getUrl() . $file->getName());
        } catch (InvalidStateException $e) {
            if ($e->getMessage() !== "Resource '" . $file->getUrl() . $file->getName() . "' already exists in the list.") {
                throw $e;
            }
        }
    }

    private function check(VirtualFile $file, $privilege) {
        try {
            return $this->user->isAllowed($file->getUrl() . $file->getName(), $privilege);
        } catch(InvalidStateException $e) {
            throw new FileNotFoundException("File " . $file->getUrl() . $file->getName() . " not found or user is not logged in the system");
        }
    }
    
    /**
     * cteni obsahu souboru nebo adresare (listing)
     * @param VirtualFile $file
     */
    public function checkRead(VirtualFile $file) {
        return $this->check($file, "read");
    }

    /**
     * zapis do souboru nebo vytvareni obsahu adresare
     * @param VirtualFile $file
     */
    public function checkWrite(VirtualFile $file) {
        return $this->check($file, "write");
    }

    /**
     * spousteni souboru nebo prochazeni adresare (traverse)
     * @param VirtualFile $file
     */
    public function checkExecute(VirtualFile $file) {
        return  $this->check($file, "execute");
    }

    /**
     * mazani souboru nebo adresare
     * @param VirtualFile $file
     */
    public function checkDelete(VirtualFile $file) {
        return $this->check($file, "delete");
    }

    /**
     * cteni atributu souboru
     * @param VirtualFile $file
     */
    public function checkAttributesRead(VirtualFile $file) {
        return $this->check($file, "read attributes");
    }

    /**
     * zmena atributu souboru
     * @param VirtualFile $file
     */
    public function checkAttributesWrite(VirtualFile $file) {
        return $this->check($file, "write attributes");
    }

    /**
     * cteni pristupovych prav ostatnich uzivatelu
     * @param VirtualFile $file
     */
    public function checkPermissionsRead(VirtualFile $file) {
        return $this->check($file, "read permissions");
    }

    /**
     * prevzeti vlastnictvi souboru nebo adresare
     * @param VirtualFile $file
     */
    public function checkTakeOwnership(VirtualFile $file) {
        return $this->check($file, "take ownership");
    }
}


